package main

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"log"
	"os"
	. "qqtestprotocol"
)

//	"log"

type QQtestDB struct {
	Users map[int64]QQtestUser
}

type QQtestUser struct {
	Uid     int64
	Nick    string
	Pwd     string
	Friends []int64
}

func (t *QQtestDB) Init() error {

	t.Users = make(map[int64]QQtestUser)

	filepath := "./userdata"
	data, err1 := ioutil.ReadFile(filepath)
	if err1 != nil {
		log.Println("QQtest DB init readfile err: ", err1)
		return err1
	}

	err2 := json.Unmarshal(data, t)
	if err2 != nil {
		log.Println("QQtest DB init decoding err: ", err2)
		return err2
	}

	return nil
}

func (t *QQtestDB) save() error {
	data, err := json.Marshal(t)
	if err != nil {
		log.Println("QQtest DB save encoding err: ", err)
		return err
	}

	filepath := "./userdata"
	file, err1 := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY, 0666)
	if err1 != nil {
		log.Println("QQtest DB save openfile err: ", err1)
		return err1
	}
	defer file.Close()

	file.Truncate(0)
	n, err2 := file.Write(data)
	if err2 != nil || n != len(data) {
		log.Println("QQtest DB save writefile err: ", err2)
		return err2
	}

	return nil
}

func (t *QQtestDB) Regist(cmd Protocol_regist) (Protocol_success, error) {
	// check nick name & max id
	var maxid int64 = 100000
	for k, v := range t.Users {
		if v.Nick == cmd.Nick {
			return Protocol_success{}, errors.New("regist failed: nick conflict!")
		}
		if maxid < k {
			maxid = k
		}
	}
	// regist
	newid := maxid + 1
	t.Users[newid] = QQtestUser{Uid: newid, Nick: cmd.Nick, Pwd: cmd.Pwd}

	// save
	t.save()

	data := Protocol_success{Cmd: "success", Uid: newid, Nick: cmd.Nick, Friends: t.Users[newid].Friends}
	return data, nil
}

func (t *QQtestDB) Login(cmd Protocol_login) (Protocol_success, error) {
	// 判断是否存在
	user, ok := t.Users[cmd.Uid]
	if !ok {
		return Protocol_success{}, errors.New("login failed: user is not exist!")
	}
	// 判断密码是否正确
	if user.Pwd != cmd.Pwd {
		return Protocol_success{}, errors.New("login failed: pwd is not correct!")
	}

	data := Protocol_success{Cmd: "success", Uid: user.Uid, Nick: user.Nick, Friends: user.Friends}
	return data, nil
}

func (t *QQtestDB) AddFriend(cmd Protocol_add_friend) (Protocol_success, error) {
	// 判断是否存在
	user, ok := t.Users[cmd.Uid]
	if !ok {
		return Protocol_success{}, errors.New("add friend failed: user is not exist!")
	}
	// 判断好友是否存在
	user1, ok1 := t.Users[cmd.Fid]
	if !ok1 {
		return Protocol_success{}, errors.New("add friend failed: friend is not exist!")
	}
	// 添加好友
	user.Friends = append(user.Friends, user1.Uid)
	t.Users[cmd.Uid] = user
	// save
	t.save()

	data := Protocol_success{Cmd: "success", Uid: user.Uid, Nick: user.Nick, Friends: user.Friends}
	return data, nil
}

func (t *QQtestDB) DelFriend(cmd Protocol_del_friend) (Protocol_success, error) {
	// 判断用户是否存在
	user, ok := t.Users[cmd.Uid]
	if !ok {
		return Protocol_success{}, errors.New("add friend failed: user is not exist!")
	}
	// 删除好友
	for i := 0; i < len(user.Friends); {
		if cmd.Fid == user.Friends[i] {
			user.Friends = append(user.Friends[:i], user.Friends[i+1:]...)
		} else {
			i++
		}
	}
	t.Users[cmd.Uid] = user
	// save
	t.save()

	data := Protocol_success{Cmd: "success", Uid: user.Uid, Nick: user.Nick, Friends: user.Friends}
	return data, nil
}
